from urllib.parse import quote_plus, urlencode

from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from base64 import encodebytes


def sig_cal(params_dict: dict):
    params_dict.pop('sign', None)
    # 生成拼接好的字符串
    list_str = []
    for k, v in sorted(params_dict.items()):
        if not v:
            continue
        if isinstance(v, dict):
            new_v = {}
            for _ in v.keys():
                if v[_]:
                    new_v[_] = v[_]
            v = new_v
        list_str.append(f"{k}={v}")
    pre_sign = '&'.join(list_str).replace(" ", '').replace("\'", "\"")

    # 应用私钥对签名字符串进行签名
    with open('./file/应用私钥.txt', 'rb') as f:
        key_data = f.read()
    private_key = RSA.importKey(key_data)
    signer = PKCS1_v1_5.new(private_key)
    signature = signer.sign(SHA256.new(pre_sign.encode('utf8')))

    # 执行base64编码，再转换为字符串，去除换行符
    sign = encodebytes(signature).decode('utf8').replace('\n', '')
    return sign, pre_sign


if __name__ == '__main__':
    alipay = {
        'app_id': '9021000131672903',
        'method': 'alipay.trade.page.pay',
        'format': 'JSON',
        'return_url': '',
        'charset': 'utf-8',
        'sign_type': 'RSA2',
        'sign': '',
        'timestamp': '2014-07-24 03:07:50',
        'version': '1.0',
        'notify_url': '',
        'biz_content': {
            "out_trade_no": '',
            "product_code": 'FAST_INSTANT_TRADE_PAY'
        }
    }

    sign, pre_sign = sig_cal(alipay)
    gateway = 'https://openapi-sandbox.dl.alipaydev.com/gateway.do'
    # urlencode 方法是将字典转换为url字符串，而quote_plus是直接将字符串进行urlencode编码
    pay_url = f"{gateway}?{pre_sign + quote_plus(sign)}"
    print(pay_url)
